package com.sys.basics.controller;

import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.store.pubsub.DispatchMessage;
import com.sys.basics.config.jsonRes.JsonResult;
import com.sys.basics.config.shiro.MyShiroRealm;
import com.sys.basics.config.socketio.data.DispatchData;
import com.sys.basics.config.socketio.nameSpaceListener.AbstractEventLintener;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Api(tags = "测试")
@RestController
@RequestMapping("/test")
public class TestController {
    protected JsonResult result = new JsonResult();
    @Autowired
    MyShiroRealm myShiroRealm;

    @Autowired
    SessionsSecurityManager securityManager;

    @Autowired
    AbstractEventLintener abstractEventLintener;

    @ApiOperation("用户认证缓存")
    @GetMapping("/getAuthenticationCache")
    public JsonResult getAuthenticationCache() {
        Map map = new HashMap();
        map.put("keys", myShiroRealm.getAuthenticationCache().keys());
        map.put("values", myShiroRealm.getAuthenticationCache().values());
        return result.success("获取用户认证缓存成功", map);
    }

    @ApiOperation("用户授权缓存")
    @GetMapping("/getAuthorizationCache")
    public JsonResult getAuthorizationCache() {
        Map map = new HashMap();
        map.put("keys", myShiroRealm.getAuthorizationCache().keys());
        map.put("values", myShiroRealm.getAuthorizationCache().values());
        return result.success("获取用户授权缓存成功", map);
    }

    @ApiOperation("增加session")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sessionKey", value = "session键", paramType = "query"),
            @ApiImplicitParam(name = "sessionValue", value = "session值", paramType = "query")
    })
    @GetMapping("/addSession")
    public JsonResult addSession(String sessionKey, String sessionValue) {
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute(sessionKey, sessionValue);
        return result.success("增加session成功");
    }

    @ApiOperation("删除session")
    @ApiImplicitParam(name = "sessionKey", value = "session键", paramType = "query")
    @GetMapping("/removeSession")
    public JsonResult removeSession(String sessionKey) {
        Session session = SecurityUtils.getSubject().getSession();
        if (ObjectUtils.isEmpty(session.getAttribute(sessionKey))) {
            return result.error("session键不存在");
        }
        session.removeAttribute(sessionKey);
        return result.success("删除session成功");
    }

    @ApiOperation("更新session")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sessionKey", value = "session键", paramType = "query"),
            @ApiImplicitParam(name = "sessionValue", value = "session值", paramType = "query")
    })
    @GetMapping("/updateSession")
    public JsonResult updateSession(String sessionKey, String sessionValue) {
        Session session = SecurityUtils.getSubject().getSession();
        if (ObjectUtils.isEmpty(session.getAttribute(sessionKey))) {
            return result.error("session键不存在");
        }
        session.setAttribute(sessionKey, sessionValue);
        return result.success("更新session成功");
    }

    @ApiOperation("查询session")
    @ApiImplicitParam(name = "sessionKey", value = "session键", paramType = "query")
    @GetMapping("/getSession")
    public JsonResult getSession(String sessionKey) {
        Session session = SecurityUtils.getSubject().getSession();
        return result.success("查询session成功", session.getAttribute(sessionKey));
    }

    @ApiOperation("查询sessionId")
    @GetMapping("/getSessionId")
    public JsonResult getSessionId() {
        Session session = SecurityUtils.getSubject().getSession();
        return result.success("查询sessionId成功", session.getId());
    }

    @ApiOperation("增加缓存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cacheName", value = "缓存名称", paramType = "query"),
            @ApiImplicitParam(name = "cacheKey", value = "缓存键", paramType = "query"),
            @ApiImplicitParam(name = "cacheValue", value = "缓存值", paramType = "query")
    })
    @GetMapping("/addCache")
    public JsonResult addCache(String cacheName, String cacheKey, String cacheValue) {
        securityManager.getCacheManager().getCache(cacheName).put(cacheKey, cacheValue);
        return result.success("添加缓存成功");
    }

    @ApiOperation("删除缓存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cacheName", value = "缓存名称", paramType = "query"),
            @ApiImplicitParam(name = "cacheKey", value = "缓存键", paramType = "query"),
    })
    @GetMapping("/removeCache")
    public JsonResult removeCache(String cacheName, String cacheKey) {
        securityManager.getCacheManager().getCache(cacheName).remove(cacheKey);
        return result.success("删除缓存成功");
    }

    @ApiOperation("修改缓存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cacheName", value = "缓存名称", paramType = "query"),
            @ApiImplicitParam(name = "cacheKey", value = "缓存键", paramType = "query"),
            @ApiImplicitParam(name = "cacheValue", value = "缓存值", paramType = "query")
    })
    @GetMapping("/updateCache")
    public JsonResult updateCache(String cacheName, String cacheKey, String cacheValue) {
        securityManager.getCacheManager().getCache(cacheName).put(cacheKey, cacheValue);
        return result.success("更新缓存成功");
    }

    @ApiOperation("查询缓存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cacheName", value = "缓存名称", paramType = "query"),
            @ApiImplicitParam(name = "cacheKey", value = "缓存键", paramType = "query"),
    })
    @GetMapping("/getCache")
    public JsonResult getCache(String cacheName, String cacheKey) {
        Object value = securityManager.getCacheManager().getCache(cacheName).get(cacheKey);
        return result.success("查询缓存成功", value);
    }

    @ApiOperation("nettySocketIo推送消息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "eventName", value = "事件名称", defaultValue = "pubsubtest", required = true, paramType = "query"),
            @ApiImplicitParam(name = "nameSpace", value = "命名空间", defaultValue = "/web", required = true, paramType = "query"),
            @ApiImplicitParam(name = "roomName", value = "房间名称", defaultValue = "/web", required = true, paramType = "query"),
            @ApiImplicitParam(name = "consumerId", value = "消息消费者id", defaultValue = "1", paramType = "query"),
    })
    @PostMapping("/nettySocketIoPublish")
    public JsonResult nettySocketIoPublish(@NotEmpty(message = "事件名称不能为空") String eventName,
                                     @NotEmpty(message = "命名空间不能为空") String nameSpace,
                                     @NotEmpty(message = "房间名称不能为空") String roomName,
                                     Long consumerId, @RequestBody Object data) {
        try {
            DispatchData dispatchData = new DispatchData();
            dispatchData.setConsumerId(consumerId);
            dispatchData.setData(data);
            //发布到本服务器节点以外的服务器
            abstractEventLintener.publish(eventName, nameSpace, roomName, dispatchData);
            //本服务器节点也触发推送
            Packet packet = abstractEventLintener.getPublishPacket(eventName, nameSpace, roomName, dispatchData);
            DispatchMessage dispatchMessage = new DispatchMessage(nameSpace, packet, roomName);
            abstractEventLintener.onSubscribeMessage(dispatchMessage);
        }catch (Exception e){
            return result.error("推送失败");
        }
        return result.success("推送成功");
    }
}
